/* * Copyright (C) 2006-2016 DLR, Germany * * All rights reserved * * http://www.rcenvironment.de/ */ package de.rcenvironment.toolkit.utils.common; import java.security.SecureRandom; import java.util.concurrent.ThreadLocalRandom; import org.apache.commons.codec.binary.Hex; /** * Utility class for generating common types of (usually random) identifiers. * * @author Robert Mischke */ public final class IdGenerator { /** * The (arbitrary) upper length limit of generated id strings. */ public static final int MAX_RANDOM_STRING_LENGTH = 64; private static final SecureRandom sharedSecureRandom = new SecureRandom(); // thread safe private IdGenerator() { // prevent instantiation } /** * Generates a random String of hex characters. The requested String length must be even and must not exceed * {@link #MAX_RANDOM_STRING_LENGTH}. The {@link IdGeneratorType} parameter select between computationally cheap or cryptographically * secure random generation. * * @param length the requested string length * @param generatorType whether to prioritize speed {@link IdGeneratorType#FAST} or security ( {@link IdGeneratorType#SECURE}) * @return the generated string */ public static String createRandomHexString(int length, IdGeneratorType generatorType) { validateRequestedLength(length); byte[] bytes = new byte[length / 2]; switch (generatorType) { case FAST: ThreadLocalRandom.current().nextBytes(bytes); break; case SECURE: sharedSecureRandom.nextBytes(bytes); break; default: throw new IllegalArgumentException(); } String string = endodeBytesAsHexAndValidateLength(bytes, length); return string; } /** * Generates a computationally cheap random String of hex characters. The requested String length must be even and must not exceed * {@link #MAX_RANDOM_STRING_LENGTH}. * * @param length the requested string length * @return the generated string */ public static String fastRandomHexString(int length) { return createRandomHexString(length, IdGeneratorType.FAST); } /** * Generates a cryptographically strong random String of hex characters. The requested String length must be even and must not exceed * {@link #MAX_RANDOM_STRING_LENGTH}. * * @param length the requested string length * @return the generated string */ public static String secureRandomHexString(int length) { return createRandomHexString(length, IdGeneratorType.SECURE); } private static void validateRequestedLength(int length) { if (length < 2 || length > MAX_RANDOM_STRING_LENGTH || length % 2 != 0) { throw new IllegalArgumentException("Length must be an even number between 2 and " + MAX_RANDOM_STRING_LENGTH); } } private static String endodeBytesAsHexAndValidateLength(byte[] bytes, int length) { String string = Hex.encodeHexString(bytes); if (string.length() != length) { throw new IllegalStateException("Internal consistency error - string of unexpected length: " + string); } return string; } }